﻿/*
strlen 是一个函数
sizeof 是一个操作符

strlen的函数声明：
size_t strlen(const char* p);
可以看出strlen函数接受的是一个地址参数，无论传入什么参数，它都会往地址上转化

常量字符串、字符串数组 这两种字符串在对strlen进行地址传参时，效果有所不同
要注意两者的区别

回顾：数组指针代码：
int a[5]={0};
int (*pa) [5]=a;
注意二维数组的地址和一维数组一个道理，都是首元素地址，而二维数组的首元素地址是第一行数组的地址，此时要传入的参数应该是数组指针

sizeof内部的表达式不会被计算,只关注占用的内存大小
//#include<stdio.h>
//#include<stdlib.h>
//int main() {
//	short s = 4;
//	int n = 5;
//	printf("%zd\n", sizeof(s = n + 6));//2
//	printf("%d\n", s);//4
//	return 0;
//}
//二维数组的sizeof
#include<stdio.h>
int main() {
	int a[3][4] = { 0 };
	printf("（1）%d\n", sizeof(a));
	//这里的a在sizeof内部，属于数组名的一种特殊情况，数组名一般情况下代表首元素地址，
	// 有两种特殊情况，1.sizeof(数组名)此时数组名表示整个数组 2.&数组名 此时数组名也表示整个数组
	//所以这里的sizeof(a)打印后是48
	printf("（2）%d\n", sizeof(a[0][0]));//直接代表a[0][0]处元素的大小 （int）4
	printf("（3）%d\n", sizeof(a[0]));//由于是二维数组，也是单独在sizeof内部，（这里的a[0]如果用%p打印出来是第0行首元素的地址）所以
	//属于数组名的一种特殊情况，则打印整个一行的大小 4*4=16
	printf("（4）%d\n", sizeof(a[0] + 1));//这时的a[0]不是单独的在sizeof内部了，二维数组中a[0]的这种写法本身就代表的是地址，是一整个数组
	//的地址（类型如：int (*pa0) [4]）这种，因此加1后代表的是一整个这种类型的加一变为a[1]的地址，因为是地址，所以大小为4/8
	printf("（5）%d\n", sizeof(*(a[0] + 1)));//a[1]的%p是第一行首元素的地址，解引用后代表第一行首元素  大小为4
	printf("（6）%d\n", sizeof(a + 1));//不是单独在sizeof内部，按地址处理 4/8
	printf("（7）%d\n", sizeof(*(a + 1)));//等同于a[1]，单独在sizeof内部，代表整个一行的数组大小 4*4=16
	printf("（8）%d\n", sizeof(&a[0] + 1));//a[0]=*(a+0)  再加上&,等同于a,后面再加一，仍然代表地址 4/8
	printf("（9）%d\n", sizeof(*(&a[0] + 1)));//地址解引用后代表a[1]这一整行的数组，且单独使用，大小为一行的大小 4*4=16
	printf("（10）%d\n", sizeof(*a));//代表0行的全部数组 大小 4*4=16
	printf("（11）%d\n", sizeof(a[3]));//4*4=16 虽然sizeof内容越界，但sizeof不关注内容的计算，只关注内容占内存的大小
	return 0;
}
*/